package com.yonyou.pmclouds.outter.user;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.iuap.tenant.sdk.UserCenter;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.outter.enterprise.EnterpriseInfoServerQuery;
import com.yonyou.pmclouds.user.entity.UserBatchQueryVO;
import com.yonyou.pmclouds.user.entity.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 服务端调用友互通用户中心
 */
@Slf4j
@Component
public class UserInfoServerQuery {
    @Autowired
    private EnterpriseInfoServerQuery enterpriseInfoQuery;
    //TODO 需要cache来处理
    private ObjectMapper jsonMapper;

    public UserInfoServerQuery() {
        jsonMapper = new ObjectMapper();
        // 设置反序列化时忽略vo中不存在的字段，放置平台偷偷的加字段，导致异常
        jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public String queryUserName(String id) {
        UserInfo user = queryUser(id);
        if (user != null)
            return user.getUserName();
        return null;
    }

    public UserInfo queryUser(String id) {
        UserInfo[] result = queryUsers(new String[]{id});
        if (!ArrayUtils.isEmpty(result)) {
            return result[0];
        }
        return null;
    }

    public UserInfo[] queryUsers(String[] ids) {
        String userInfos = UserCenter.getUsersByUserIds(Arrays.asList(ids));
        UserBatchQueryVO userBatchQueryVO = null;
        if (StringUtils.isEmpty(userInfos)) {
            return null;
        }
        try {
            userBatchQueryVO = jsonMapper.readValue(userInfos, UserBatchQueryVO.class);
        } catch (IOException e) {
            return null;
        }
        if (userBatchQueryVO != null) {
            return userBatchQueryVO.getUsers();
        }
        return null;
    }

    public Map<String, String> queryUserNames(String[] ids) {
        UserInfo[] t = queryUsers(ids);
        if (!ArrayUtils.isEmpty(t)) {
            Map<String, String> result = new HashMap<>(t.length);
            for (UserInfo user : t) {
                UserInfo u = user;
                if (u != null) {
                    result.put(u.getUserId(), u.getUserName());
                }
            }
            return result;
        }
        return new HashMap<>();
    }

    public Map<String, UserInfo> extractUserInfoFromBeans(Object[] beans, String[] userIdFields) {
        if (ArrayUtils.isEmpty(beans)) {
            return new HashMap<>();
        }
        Set<String> userIds = new HashSet<>();
        for (String userIdField : userIdFields) {
            Method read = BeanHelper.getGetMethod(beans[0], userIdField);
            if (read == null) {
                continue;
            }
            for (Object src : beans) {
                try {
                    String id = (String) read.invoke(src);
                    userIds.add(id);
                } catch (Exception e) {
                    log.error("read userid error {}", read);
                }
            }
        }
        UserInfo[] users = queryUsers(userIds.toArray(new String[userIds.size()]));
        if (ArrayUtils.isEmpty(users)) {
            return new HashMap<>();
        }
        Map<String, UserInfo> result = new HashMap<>(users.length);
        for (UserInfo user : users) {
            result.put(user.getUserId(), user);
        }
        return result;
    }

    public void tranUserInfoField(Object[] beans, String[] userIdFields, String[] userNameFields) {
        tranUserInfoField(beans, beans, userIdFields, userNameFields);
    }

    public void tranUserInfoField(Object[] srcs, Object[] dests,
                                  String[] userIdFields, String[] userNameFields) {
        if (ArrayUtils.isEmpty(srcs) || ArrayUtils.isEmpty(dests) || srcs.length != dests.length) {
            return;
        }
        Set<String> userIds = new HashSet<>();
        for (String userIdField : userIdFields) {
            Method read = BeanHelper.getGetMethod(srcs[0], userIdField);
            if (read == null) {
                continue;
            }
            for (Object src : srcs) {
                try {
                    String id = (String) read.invoke(src);
                    userIds.add(id);
                } catch (Exception e) {
                    log.error("read userid error {}", read);
                }
            }
        }
        Map<String, String> userIdNameMap = queryUserNames(userIds.toArray(new String[userIds.size()]));
        for (int i = 0; i < userIdFields.length; i++) {
            Method write = BeanHelper.getSetMethod(dests[0], userNameFields[i]);
            Method read = BeanHelper.getGetMethod(srcs[0], userIdFields[i]);
            if (write == null) {
                continue;
            }
            for (int j = 0; j < srcs.length; j++) {
                try {
                    write.invoke(dests[j], userIdNameMap.get(read.invoke(srcs[j])));
                } catch (Exception e) {
                    log.error("write userid error {}", write);
                }
            }
        }
    }

    public static String CONTACT_MOBILE = "mobile";
    public static String CONTACT_EMAIL = "email";

    /**
     * 方法功能描述：根据联系方式获取用户ID。
     *
     * <b>参数说明</b>
     *
     * @param mobile
     * @param email
     * @return
     * @throws BusinessException
     * @author zhangwce
     * @time 2018年1月25日 下午10:39:40
     */
    public UserInfo getUserIdByContact(String mobile, String email) throws BusinessException {

        if (StringUtils.isEmpty(mobile) && StringUtils.isEmpty(email))
            return null;

        UserInfo[] userInfos = null;
        if (!StringUtils.isEmpty(mobile)) {
            userInfos = getUserByContact(mobile, CONTACT_MOBILE);
        } else if (!StringUtils.isEmpty(email)) {
            userInfos = getUserByContact(email, CONTACT_EMAIL);
        }

        if (userInfos == null || userInfos.length == 0)
            return null;
        return userInfos[0];
    }

    private UserInfo[] getUserByContact(String contact, String method) throws BusinessException {

        if (contact == null)
            return null;

        String userInfo = null;
        if (CONTACT_MOBILE.equals(method)) {
            userInfo = UserCenter.getUserByContact(contact, "mobile");
        } else if (CONTACT_EMAIL.equals(method)) {
            userInfo = UserCenter.getUserByContact(contact, "email");
        }

        UserBatchQueryVO userBatchQueryVO = null;
        try {
            userBatchQueryVO = jsonMapper.readValue(userInfo, UserBatchQueryVO.class);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (Integer.valueOf(0).equals(userBatchQueryVO.getStatus())) {
            log.error("根据联系方式获取用户出错");
            throw new BusinessException("根据联系方式获取用户出错");
        }

        UserInfo[] userInfos = userBatchQueryVO.getUsers();
        return userInfos;
    }

    public String queryUserByCode(String userCode) {
        String result = UserCenter.getUserByCode(userCode);

        Map<String, Object> resultMap = null;
        try {
            resultMap = jsonMapper.readValue(result, Map.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }

        if (resultMap == null)
            return null;

        if (resultMap != null)
            return (String) resultMap.get("userId");
        return null;
    }

}
